#include <type_traits>
#include <iostream>

// template <unsigned N>
// struct Factorial {
//	static const unsigned value = N * Factorial<N - 1>::value;
// };
//
//// 终止条件特化
// template <>
// struct Factorial<0> {
//	static const unsigned value = 1;
// };
//
// int main()
//{
//	constexpr unsigned fact5 = Factorial<5>::value; // 编译时计算出120
//
//	return 0;
// }

// template<typename T>
// struct is_pointer
// {
// 	static constexpr bool value = false;
// };

// // 针对指针类型的偏特化
// template<typename T>
// struct is_pointer<T*>
// {
// 	static constexpr bool value = true;
// };

// // 主模板，默认情况类型不同
// template<typename T, typename U>
// struct is_same
// {
// 	static constexpr bool value = false;
// };

// // 特化版本，当两个类型相同时
// template<typename T>
// struct is_same<T, T>
// {
// 	static constexpr bool value = true;
// };

// // 移除 const
// // 主模板，默认情况下不改变类型
// template <typename T>
// struct remove_const
// {
// 	using type = T;
// };

// // 针对 const T 的特化版本，移除 const
// template <typename T>
// struct remove_const<const T>
// {
// 	using type = T;
// };

// int main()
// {
// 	static_assert(is_pointer<int*>::value, "int* is a pointer");
// 	// static_assert(is_pointer<int>::value, "int is not a pointer");

// 	static_assert(is_same<int, int>::value, "int and int should be the same");
//     // static_assert(is_same<int, float>::value, "int and float should be different");

// 	static_assert(is_same<remove_const<int>::type, int>::value, "is not int");
// 	static_assert(is_same<remove_const<const int>::type, int>::value, "is not int");

// 	remove_const<const int>::type x = 0;
// 	x++;

// 	return 0;
// }

// // 1、基础类型检查
// std::is_void<void>::value; // true
// std::is_integral<int>::value; // true
// std::is_floating_point<float>::value; // true
// std::is_pointer<int*>::value; // true
// std::is_reference<int&>::value; // true
// std::is_const<const int>::value; // true

// // 2、复合类型检查
// std::is_function<void()>::value; // true
// std::is_member_object_pointer<int (Foo::*)>::value; // true
// std::is_compound<std::string>::value; // true (⾮基础类型)

// // 3、类型关系检查
// std::is_same<int, int32_t>::value; // 取决于平台
// std::is_base_of<Base, Derived>::value;
// std::is_convertible<From, To>::value;

// // 4、类型修改
// std::add_const<int>::type; // const int
// std::add_pointer<int>::type; // int*
// std::add_lvalue_reference<int>::type; // int&
// std::remove_const<const int>::type; // int
// std::remove_pointer<int*>::type; // int
// std::remove_reference<int&>::type; // int
// // 4、条件类型选择
// std::conditional<true, int, float>::type; // int
// std::conditional<false, int, float>::type; // float

// // 5、类型推导
// // 函数的返回结果类型
// std::result_of<F(Args...)>::type; // C++17以后被废弃
// std::invoke_result<F, Args...>::type; // C++17以后使⽤这个
// template<class F, class... Args>
// using invoke_result_t = typename invoke_result<F, Args...>::type;

// // C++11⽅式
// std::is_integral<int>::value;
// std::remove_const<const int>::type;

// // C++14、C++17 更简洁的方式
// std::is_integral_v<int>;
// std::remove_const_t<const int>;

// // C++17 引⼊的辅助变量模板
// template<typename T>
// inline constexpr bool is_integral_v = is_integral<T>::value;

// // C++14 引⼊的辅助别名模板
// template<typename T>
// using remove_const_t = typename remove_const<T>::type;

// template <typename T>
// auto foo(T x) -> decltype(++x, void())
// {
//     std::cout << "foo(T): " << x << " (can be incremented)\n";
// }

// // C++ 17 使⽤void_t优化上⾯的写法
// // template<typename T>
// // auto foo(T x) -> std::void_t<decltype(++x)> {
// //  std::cout << "foo(T): " << x << " (can be incremented)\n";
// // }
// //  版本2：回退版本

// void foo(...)
// {
//     std::cout << "foo(...): fallback (cannot increment)\n";
// }

// int main()
// {
//     foo(42);                  // 调⽤版本1（int ⽀持 ++x）
//     foo(std::string("1111")); // 调⽤版本2（string 不⽀持 ++x）

//     return 0;
// }

// #include <type_traits>
// #include <iostream>

// // 对于整数类型启⽤此重载
// template <typename T>
// typename std::enable_if_t<std::is_integral_v<T>, T>
// add_one(T t)
// {
//     return t + 1;
// }

// // 对于浮点类型启⽤此重载 
// template <typename T>
// typename std::enable_if_t<std::is_floating_point_v<T>, T> add_one(T t)
// {
//     return t + 2.0;
// }

// // 模板参数的检查 
// template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
// void process_integer(T value)
// {
//     // 只接受整数类型
// }

// int main()
// {
//     std::cout << add_one(5) << "\n";    // 调用整数版本，输出6
//     std::cout << add_one(3.14) << "\n"; // 调用浮点版本，输出4.14
//     // add_one("hello"); // 编译错误，没有匹配的重载
//     process_integer(1);
//     // process_integer(1.1); // 编译错误，没有匹配的重载
// }